package org.liaoxuefeng.study;

import lombok.val;
import org.testng.annotations.Test;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author: 默苍璃
 * @date: 2022-09-28 16:48
 * JDBC事务操作
 * <p>
 * 数据库事务具有ACID特性：
 * <p>
 * Atomicity：原子性
 * Consistency：一致性
 * Isolation：隔离性
 * Durability：持久性
 */
public class JDBCTransaction {

    /**
     * JDBC连接的URL, 不同数据库有不同的格式:
     */
    final String JDBC_URL = "jdbc:mysql://localhost/jdbc?useSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8";
    final String JDBC_USER = "root";
    final String JDBC_PASSWORD = "root";


    /**
     * JDBC事务操作
     */
    @Test
    public void test() throws SQLException {
        //获取连接
        val connection = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);

        // 关闭自动提交:
        connection.setAutoCommit(false);

        //插入sql语句
        String sql = "insert into students  (grade, name, gender ,score) values(?,?,?,?)";
        //创建预编译声明
        val preparedStatement = connection.prepareStatement(sql);
        //给查询条件赋值   索引从1开始
        preparedStatement.setObject(1, (byte) 3);
        preparedStatement.setObject(2, "俞家伟");
        preparedStatement.setObject(3, 2);
        preparedStatement.setObject(4, 100);

        //执行插入sql语句(不用传参数)
        val result = preparedStatement.executeUpdate();

        // 提交事务:
        connection.commit();

        //打印返回数据（插入的记录数量）
        System.out.println(result);

        preparedStatement.close();
        connection.close();
    }


    /**
     * JDBC事务操作
     * 事务回滚
     */
    @Test
    public void test1() throws SQLException {
        //获取连接
        val connection = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);

        try {

            // 关闭自动提交:
            connection.setAutoCommit(false);

            //插入sql语句
            String sql = "insert into students  (grade, name, gender ,score) values(?,?,?,?)";
            //创建预编译声明
            val preparedStatement = connection.prepareStatement(sql);
            //给查询条件赋值   索引从1开始
            preparedStatement.setObject(1, (byte) 3);
            preparedStatement.setObject(2, "江华改");
            preparedStatement.setObject(3, 2);
            preparedStatement.setObject(4, 100);

            //执行插入sql语句(不用传参数)
            val result = preparedStatement.executeUpdate();
            val result1 = preparedStatement.executeUpdate();

            //模拟异常
            int i = 1 / 0;
            // 提交事务:
            connection.commit();

            //打印返回数据（插入的记录数量）
            System.out.println(result);

            preparedStatement.close();

        } catch (Exception e) {
            System.out.println("出现了异常！");
            connection.rollback();
        } finally {
            connection.close();
        }

    }


}
